package 简单.滑动窗口;

/**
 * 给你一个 非负 整数数组 nums 和一个整数 k 。
 * 如果一个数组中所有元素的按位或运算 OR 的值 至少 为 k ，那么我们称这个数组是 特别的 。
 * 请你返回 nums 中 最短特别非空子数组
 * 的长度，如果特别子数组不存在，那么返回 -1 。
 *
 * @ https://leetcode.cn/problems/shortest-subarray-with-or-at-least-k-i/description/?envType=daily-question&envId=2025-01-16
 * @date 2025/01/16
 */
public class 或值至少K的最短子数组I_3095 {

    public static void main(String[] args) {

        或值至少K的最短子数组I_3095 impl = new 或值至少K的最短子数组I_3095();
        System.out.println(impl.minimumSubarrayLength(new int[]{1, 2}, 0));
        System.out.println(((1 >> 0) & 1));

    }

    public int minimumSubarrayLength(int[] nums, int k) {
        if (k == 0) {
            return 1;
        }
        int ans = nums.length + 1;
        int[] cnt = new int[32];

        int left = 0, right = 0;
        while (left < nums.length) {

            while (right < nums.length && getNum(cnt) < k) {
                for (int i = 0; i < 32; i++) {
                    if (((nums[right] >> i) & 1) == 1) {
                        cnt[i]++;
                    }
                }

                right++;
            }

            if (getNum(cnt) >= k) {
                ans = Math.min(ans, right - left);
            }
            for (int i = 0; i < 32; i++) {
                if ((nums[left] >> i & 1) == 1) {
                    cnt[i]--;
                }
            }
            left++;

        }
        return ans == nums.length + 1 ? -1 : ans;
    }

    private int getNum(int[] cnt) {
        int num = 0;
        for (int i = 0; i < cnt.length; i++) {
            if (cnt[i] > 0) {
                num += 1 << i;
            }
        }
        return num;
    }

}
